package com.ddx.pay;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.Header;
import org.apache.http.HttpHeaders;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.methods.RequestBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.message.BasicHeader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @author dudianbo
 * @ClassName: ${CLASSNAME}
 * @Description: ${DESCRIPTION}
 * @date 2018/8/21
 */
@Service
public class WeixinPay {
    private static final Logger logger = LoggerFactory.getLogger(WeixinPay.class);
    /**
     * 商户号
     */
    @Value("${MCH_ID}")
    private  String MCH_ID;
    /**
     * 公众账号ID
     */
    @Value("${APP_ID}")
    private  String APP_ID;
    /**
     * 链接地址
     */
    @Value("${MCH_URI}")
    private  String MCH_URI;
    /**
     * api_key
     */
    @Value("${API_KEY}")
    private  String API_KEY;

    @Value("${NOTIFY_URL}")
    private String notifyurl;

    protected static Header xmlHeader = new BasicHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_XML.toString());

    /**
     * 统一下单
     *
     * @param weChatRequestPayDto
     * @param
     * @return payUnifiedorder
     */
    public  WeChatPayDto payUnifiedorder(WeChatRequestPayDto weChatRequestPayDto) {
        long s = System.currentTimeMillis();
        Unifiedorder unifiedorder = new Unifiedorder();
        unifiedorder.setBody(weChatRequestPayDto.getBody());
        unifiedorder.setOut_trade_no(weChatRequestPayDto.getOut_trade_no());
        unifiedorder.setTotal_fee(weChatRequestPayDto.getTotal_fee());
        unifiedorder.setSpbill_create_ip(weChatRequestPayDto.getSpbill_create_ip());
        unifiedorder.setTrade_type(weChatRequestPayDto.getTrade_type());
        unifiedorder.setNotify_url(notifyurl);
        unifiedorder.setAppid(APP_ID);//PropertiesUtilWeChat.get("appid")
        unifiedorder.setMch_id(MCH_ID);
        unifiedorder.setNonce_str(UUID.randomUUID().toString().replace("-", ""));
        unifiedorder.setOpenid(weChatRequestPayDto.getWxOpanid());
        unifiedorder.setSub_mch_id(weChatRequestPayDto.getSub_mch_id());
        unifiedorder.setSub_appid(weChatRequestPayDto.getSub_appid());
        unifiedorder.setSub_openid(weChatRequestPayDto.getSub_openid());
        unifiedorder.setTime_start(weChatRequestPayDto.getTime_start());
        unifiedorder.setTime_expire(weChatRequestPayDto.getTime_expire());
        if (!StringUtils.isEmpty(weChatRequestPayDto.getDevice_info())) {
            logger.info("下单设备号:" + weChatRequestPayDto.getDevice_info());
            unifiedorder.setDevice_info(weChatRequestPayDto.getDevice_info());
        } else {
            logger.info("设备号为空");
        }

        Map<String, String> map = MapUtil.objectToMap(unifiedorder);
        logger.info("统一下单请求数据：" + map.toString());

        String sign = SignatureUtil.generateSign(map, API_KEY);
        logger.info("签名信息sgin：" + sign);
        unifiedorder.setSign(sign);
        String unifiedorderXML = XMLConverUtil.convertToXML(unifiedorder);
        HttpUriRequest httpUriRequest = RequestBuilder.post().setHeader(xmlHeader)
                .setUri(MCH_URI + "/pay/unifiedorder")
                .setEntity(new StringEntity(unifiedorderXML, Charset.forName("utf-8")))
                .build();
        UnifiedorderResult unifiedorderResult = LocalHttpClient.executeXmlResult(httpUriRequest, UnifiedorderResult.class);
        WeChatPayDto weChatPayDto = new WeChatPayDto();

        logger.info("统一下单返回结果:" + unifiedorderResult.toString());
        weChatPayDto.setWxtradetype(unifiedorder.getTrade_type());
        weChatPayDto.setAppId(APP_ID);
        weChatPayDto.setPartnerid(MCH_ID);
        weChatPayDto.setPrepayid(unifiedorderResult.getPrepay_id());
        weChatPayDto.setNonceStr(unifiedorderResult.getNonce_str());
        weChatPayDto.setAppkey(API_KEY);
        weChatPayDto.setNotifyurl(URLEncoder.encode(notifyurl));
        weChatPayDto.setMwebUrl(unifiedorderResult.getMweb_url());
        logger.info("微信统一下单耗时ms:" + (System.currentTimeMillis() - s));
        return weChatPayDto;
    }
    /**
     * 查询订单
     *
     * @param tradeno
     * @return
     */
    public  MchOrderInfoResult payOrderquery(String tradeno) {
        MchOrderquery mchOrderquery=new MchOrderquery();
        mchOrderquery.setOut_trade_no(tradeno);
        mchOrderquery.setAppid(APP_ID);
        mchOrderquery.setMch_id(MCH_ID);
        mchOrderquery.setNonce_str(UUID.randomUUID().toString().replace("-", ""));
        Map<String, String> map = MapUtil.objectToMap(mchOrderquery);
        String sign = SignatureUtil.generateSign(map, API_KEY);
        mchOrderquery.setSign(sign);
        String closeorderXML = XMLConverUtil.convertToXML(mchOrderquery);


        //解决IP地址访问报错问题
        HostnameVerifier hv = new HostnameVerifier() {
            public boolean verify(String urlHostName, SSLSession session) {
                System.out.println("Warning: URL Host: " + urlHostName + " vs. "
                        + session.getPeerHost());
                return true;
            }
        };
        HttpsURLConnection.setDefaultHostnameVerifier(hv);

        HttpUriRequest httpUriRequest = RequestBuilder.post()
                .setHeader(xmlHeader)
                .setUri(MCH_URI + "/pay/orderquery")
                .setEntity(new StringEntity(closeorderXML, Charset.forName("utf-8")))
                .build();
        MchOrderInfoResult mchOrderInfoResult=LocalHttpClient.executeXmlResult(httpUriRequest, MchOrderInfoResult.class);
        return mchOrderInfoResult;
    }
    /**
     * 封装jsapi支付参数
     * @param weChatPayDto
     * @return
     */
    public Map<String, String> jsApiPay(WeChatPayDto weChatPayDto){
        Map<String, String> map = new HashMap<>();
        map.put("appId",APP_ID);
        long s = System.currentTimeMillis()/100;
        map.put("timeStamp",String.valueOf(s));
        map.put("nonceStr",UUID.randomUUID().toString().replace("-", ""));
        map.put("package","prepay_id="+weChatPayDto.getPrepayid());
        String sign = SignatureUtil.generateSign(map, API_KEY);
        map.put("paySign",sign);
        return map;
    }

}
